package com.tianyu.service.tcp;


import com.alibaba.fastjson2.JSONObject;
import com.tianyu.service.http.HttpRequest;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.timeout.IdleStateHandler;
import lombok.extern.slf4j.Slf4j;

import java.net.InetSocketAddress;
import java.util.Objects;

import static com.tianyu.service.cache.DataCacheService.tianyuTcpChannelMap;

@Slf4j
public class TcpClient {

    /**
     * 云盒客户端连接创建对象 [TCP客户端连接池]
     */
    private static final EventLoopGroup LOOP_GROUP = new NioEventLoopGroup();

    public TcpClient(TianyuCompanyMessage message) {
        if (message.getToken() != null) {
            final Channel channel = newTcpClient(message);
            tianyuTcpChannelMap.put(message.getCompanyId(), channel);
        } else {
            JSONObject login = HttpRequest.cloudPlatformCompanyLogin(
                    message.getServerHttpPrefix(),
                    message.getCpAccessKey(),
                    message.getCpAccessSecret()
            );
            if (Objects.isNull(login)) {
                throw new IllegalStateException("登录异常...");
            } else if (login.get("state").equals(1)) {
                log.info("云平台企业账户[{}] Login Successfully! ", login.get("companyId"));
                final Channel channel = newTcpClient(message);
                tianyuTcpChannelMap.put(message.getCompanyId(), channel);
            } else {
                throw new IllegalStateException("登录异常...");
            }
        }
    }

    public Channel newTcpClient(TianyuCompanyMessage message) {
        Bootstrap bootstrap = new Bootstrap();
        bootstrap.group(LOOP_GROUP)
                .option(ChannelOption.TCP_NODELAY, true)
                .channel(NioSocketChannel.class)
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel socketChannel) {
                        socketChannel.pipeline().addLast("encoder", new Encoder());
                        socketChannel.pipeline().addLast(new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 2,
                                2, 0, 4, true));
                        socketChannel.pipeline().addLast("decoder", new Decoder());
                        socketChannel.pipeline().addLast(new IdleStateHandler(3, 3, 3));
                        socketChannel.pipeline().addLast(new TcpClientChannelHandler(message));
                    }
                });
        Channel channel;
        try {
            ChannelFuture future = bootstrap.connect(new InetSocketAddress(message.getServerTcpHost(), message.getServerTcpPort())).sync();
            channel = future.channel();
        } catch (InterruptedException e) {
            log.error(e.getCause().getMessage());
            return null;
        }
        return channel;
    }

}